package it.univpm.diiga.memorysim.kernel.shared;

import it.univpm.diiga.memorysim.kernel.shared.tree.MovingBox;

import java.util.ArrayList;
import java.util.Hashtable;

public class Kernel {

	private Parameters p= new Parameters();
	
	private ArrayList<SimEvent> events=new ArrayList<SimEvent>();
	private EventsDisk eventsDisk=new EventsDisk();
		
	//algoritmi DUMMY
	private String[] AlgorithmCentMem= new String[]{"Dummy"};
	private String[] AlgorithmSecMem= new String[]{"Random"};
	private boolean SimType1=false,SimType2=false;
	
	public Kernel(){	}
	
	public String[] getAlgorithmSecMem(){
		return AlgorithmSecMem;
	}
	
	public String[] getAlgorithmCentMem(){
		return AlgorithmCentMem;
	}
	
	public void activeSimType1(){
		System.out.println("SIMULAZIONE TIPO1 ATTIVA");
		SimType1=true;
	}
	
	public void activeSimType2(){
		System.out.println("SIMULAZIONE TIPO2 ATTIVA");
		SimType2=true;
	}
	
	public void setDimSOMemory(int mem){
		System.out.println("Memoria Sistema Operativo: "+mem);
		p.setDimSOMemory(mem);
	}

	public boolean isactiveSimType1() {
		return SimType1;
	}
	public boolean isactiveSimType2() {
		return SimType2;
	}

	public void selectedAlgorithmSecMem(String algSelected) {
		System.out.println("Algorimtmo Selezionato: "+algSelected);
	}

	public void selectedAlgorithmCentMem(String algSelected) {
		System.out.println("Algorimtmo Selezionato: "+algSelected);
	}

	public void setHardware(int memorycentraldata,int swapdata,int blockdata,int hdddimensiondata,int trasferratedata,
			int seekdata,int revolutiontimedata, int hdddimensionblockdata) {
		System.out.println("Caratteristiche Hardware configurate!!");
		p.setDimensionCentralMemory(memorycentraldata);
		p.setDimensionSwap(swapdata);
		p.setDimensionBlock(blockdata);
		p.setSecondaryMemory(hdddimensiondata, seekdata, hdddimensionblockdata, trasferratedata, revolutiontimedata);
	}

	public void setListProcess(ArrayList<Process> listProcess, ArrayList<String> centralMemoryP, ArrayList<String> swapMemoryP) {
		System.out.println("Lista dei Processi Importati");
		p.setProcesses(listProcess);
		p.memstart(centralMemoryP,swapMemoryP);
	}

	public void setListProcessRequest(ArrayList<ProcessRequest> listProcessRequest){
		System.out.println("Richieste di Processi Importate");
		p.setProcessList(listProcessRequest);
	}

	public void setFileSystem(MovingBox root) {
		System.out.println("File System Importato");
		Parameters.setFileSystem(root);
	}

	public void setListFileRequest(ArrayList<FileRequest> listFileRequest) {
		System.out.println("Richieste di File Importate");
	}
	
	public void start_simulation(){

		//TABELLA EVENTI MEMORIA
		//TODO
		events=new ArrayList<SimEvent>();
		events.add(new SimEvent(1,"Stato Iniziale",1,StatoInizialeMemoriaCentrale(),StatoInizialeMemoriaSwap(),0));  //situazione iniziale memoria centrale
		events.add(new SimEvent(1,"Page Fault",1,3,StatoInizialeMemoriaCentrale(),StatoInizialeMemoriaSwap(),2));
		events.add(new SimEvent(1,"GET",3,MemoriaCentrale1(),MemoriaSwap1(),3));
		events.add(new SimEvent(1,"Page Fault",2,4,MemoriaCentrale1(),MemoriaSwap1(),5));
		events.add(new SimEvent(1,"GET",4,MemoriaCentrale2(),MemoriaSwap2(),6));
		events.add(new SimEvent(3,"GET",4,MemoriaCentrale2a(),MemoriaSwap2(),8));
		
		//TABELLA EVENTI DISCO
		eventsDisk.HDDevents=new ArrayList<SimEvent>();
			//situazione Iniziale
		eventsDisk.HDDevents.add(new SimEvent("","/","Stato Inziale","0"));
			
		eventsDisk.HDDevents.add(new SimEvent("1.txt","/Disco/prova/1.txt","Scrittura","2")); 
		eventsDisk.HDDevents.add(new SimEvent("2.txt","/Disco/prova/2.txt","Scrittura","4")); 
		eventsDisk.HDDevents.add(new SimEvent("1.txt","/Disco/prova/1.txt","Scrittura","8"));
		eventsDisk.HDDevents.add(new SimEvent("4.txt","/Disco/prova/4.txt","Scrittura","10"));
		eventsDisk.HDDevents.add(new SimEvent("5.txt","/Disco/prova/5.txt","Scrittura","12"));
		eventsDisk.HDDevents.add(new SimEvent("4.txt","/Disco/prova/4.txt","Lettura","13"));
		eventsDisk.HDDevents.add(new SimEvent("fine.txt","/Disco/prova/fine.txt","Scrittura","15"));
		eventsDisk.HDDevents.add(new SimEvent("full","full","Scrittura","15"));
		
		//uno stato dell'HDD
		//al caricamento tenere conto che \per valori inferiori al Mega si considera valore 1.
		
		
		eventsDisk.HDDstate = new Hashtable<Integer, ArrayList<Integer>>();
		eventsDisk.HDDstate.put(0, default1());
		eventsDisk.HDDstate.put(1, Evento1_X());
		eventsDisk.HDDstate.put(2, Evento2_X());
		eventsDisk.HDDstate.put(3, Evento3_X());
		eventsDisk.HDDstate.put(4, Evento4_X());
		eventsDisk.HDDstate.put(5, Evento5_X());
		eventsDisk.HDDstate.put(6, Evento5_X());
		eventsDisk.HDDstate.put(7, Evento6_X());
		eventsDisk.HDDstate.put(8, Evento7_X());
	
		eventsDisk.HDDlistFiles= new Hashtable<Integer, ArrayList<String>>();
		eventsDisk.HDDlistFiles.put(0,default2());
		eventsDisk.HDDlistFiles.put(1,Evento1_Y());
		eventsDisk.HDDlistFiles.put(2,Evento2_Y());
		eventsDisk.HDDlistFiles.put(3,Evento3_Y());
		eventsDisk.HDDlistFiles.put(4,Evento4_Y());
		eventsDisk.HDDlistFiles.put(5,Evento5_Y());
		eventsDisk.HDDlistFiles.put(6,Evento5_Y());
		eventsDisk.HDDlistFiles.put(7,Evento6_Y());
		eventsDisk.HDDlistFiles.put(8,Evento7_Y());
	}
	
	private ArrayList<Integer> Evento7_X() {
		ArrayList<Integer> HDDarea1 = new ArrayList<Integer>();
		HDDarea1.add(163840);
		return HDDarea1;
	}
	private ArrayList<String> Evento7_Y() {
		ArrayList<String> HDDfiles1 = new ArrayList<String>();
		HDDfiles1.add("/S.O.");
		return HDDfiles1;
	}
	
	private ArrayList<Integer> Evento6_X() {
		ArrayList<Integer> HDDarea1 = new ArrayList<Integer>();
		HDDarea1.add(2000);
		HDDarea1.add(3000);
		HDDarea1.add(6000);
		HDDarea1.add(2500);
		HDDarea1.add(5000);
		HDDarea1.add(500);
		HDDarea1.add(300);
		HDDarea1.add(3000);
		return HDDarea1;
	}
	
	
	private ArrayList<String> Evento6_Y() {
		ArrayList<String> HDDfiles1 = new ArrayList<String>();
		HDDfiles1.add("/Disco");
		HDDfiles1.add("/Disco/prova1");
		HDDfiles1.add("/Disco/prova");
		HDDfiles1.add("/Disco/prova/4.txt");
		HDDfiles1.add("/Disco/prova/5.txt");
		HDDfiles1.add("-1");
		HDDfiles1.add("/Disco/prova/2.txt");
		HDDfiles1.add("/Disco/prova/fine.txt");
		return HDDfiles1;
	}
	
	
	private ArrayList<Integer> Evento5_X() {
		ArrayList<Integer> HDDarea1 = new ArrayList<Integer>();
		HDDarea1.add(2000);
		HDDarea1.add(3000);
		HDDarea1.add(6000);
		HDDarea1.add(2500);
		HDDarea1.add(5000);
		HDDarea1.add(500);
		HDDarea1.add(300);
		return HDDarea1;
	}
	
	
	private ArrayList<String> Evento5_Y() {
		ArrayList<String> HDDfiles1 = new ArrayList<String>();
		HDDfiles1.add("/Disco");
		HDDfiles1.add("/Disco/prova1");
		HDDfiles1.add("/Disco/prova");
		HDDfiles1.add("/Disco/prova/4.txt");
		HDDfiles1.add("/Disco/prova/5.txt");
		HDDfiles1.add("-1");
		HDDfiles1.add("/Disco/prova/2.txt");
		return HDDfiles1;
	}
	
	
	private ArrayList<Integer> Evento4_X() {
		ArrayList<Integer> HDDarea1 = new ArrayList<Integer>();
		HDDarea1.add(2000);
		HDDarea1.add(3000);
		HDDarea1.add(6000);
		HDDarea1.add(2500);
		HDDarea1.add(5500);
		HDDarea1.add(300);
		return HDDarea1;
	}
	
	
	private ArrayList<String> Evento4_Y() {
		ArrayList<String> HDDfiles1 = new ArrayList<String>();
		HDDfiles1.add("/Disco");
		HDDfiles1.add("/Disco/prova1");
		HDDfiles1.add("/Disco/prova");
		HDDfiles1.add("/Disco/prova/4.txt");
		HDDfiles1.add("-1");
		HDDfiles1.add("/Disco/prova/2.txt");
		return HDDfiles1;
	}
	
	
	private ArrayList<String> Evento3_Y() {
		ArrayList<String> HDDfiles1 = new ArrayList<String>();
		HDDfiles1.add("/Disco");
		HDDfiles1.add("/Disco/prova1");
		HDDfiles1.add("/Disco/prova");
		HDDfiles1.add("-1");
		HDDfiles1.add("/Disco/prova/2.txt");
		return HDDfiles1;
	}
	
	private ArrayList<Integer> Evento3_X() {
		ArrayList<Integer> HDDarea1 = new ArrayList<Integer>();
		HDDarea1.add(2000);
		HDDarea1.add(3000);
		HDDarea1.add(6000);
		HDDarea1.add(8000);
		HDDarea1.add(300);
		return HDDarea1;
	}
	
	private ArrayList<Integer> Evento2_X() {
		ArrayList<Integer> HDDarea1 = new ArrayList<Integer>();
		HDDarea1.add(2000);
		HDDarea1.add(3000);
		HDDarea1.add(6000);
		HDDarea1.add(8000);
		HDDarea1.add(300);
		return HDDarea1;
	}
	
	private ArrayList<String> Evento2_Y() {
		ArrayList<String> HDDfiles1 = new ArrayList<String>();
		HDDfiles1.add("/Disco");
		HDDfiles1.add("/Disco/prova1");
		HDDfiles1.add("/Disco/prova");
		HDDfiles1.add("/Disco/prova/1.txt");
		HDDfiles1.add("/Disco/prova/2.txt");
		return HDDfiles1;
	}
		
	private ArrayList<Integer> Evento1_X() {
		ArrayList<Integer> HDDarea1 = new ArrayList<Integer>();
		HDDarea1.add(2000);
		HDDarea1.add(3000);
		HDDarea1.add(6000);
		HDDarea1.add(8000);
		return HDDarea1;
	}
	
	private ArrayList<String> Evento1_Y() {
		ArrayList<String> HDDfiles1 = new ArrayList<String>();
		HDDfiles1.add("/Disco");
		HDDfiles1.add("/Disco/prova1");
		HDDfiles1.add("/Disco/prova");
		HDDfiles1.add("/Disco/prova/1.txt");
		return HDDfiles1;
	}
	
	private ArrayList<String> default2() {
		ArrayList<String> HDDfiles1 = new ArrayList<String>();
		HDDfiles1.add("/Disco");
		HDDfiles1.add("/Disco/prova1");
		HDDfiles1.add("/Disco/prova");
		HDDfiles1.add("/Disco/prova/1.txt");
		return HDDfiles1;
	}

	private ArrayList<Integer> default1() {
		ArrayList<Integer> HDDarea1 = new ArrayList<Integer>();
		HDDarea1.add(2000);
		HDDarea1.add(3000);
		HDDarea1.add(6000);
		HDDarea1.add(5000);
		return HDDarea1;
	}

	public ArrayList<SimEvent> getResult1(){
		return events;
	}
	
	public EventsDisk getResult2(){
		return eventsDisk;
	}
	
	private Hashtable<Integer, ProcessRequest> StatoInizialeMemoriaCentrale() {
		Hashtable<Integer, ProcessRequest> InitMem = new Hashtable<Integer, ProcessRequest>();
		InitMem.put(0, new ProcessRequest(1,1,"r"));
		InitMem.put(1, new ProcessRequest(1,2,"r"));
		InitMem.put(2, new ProcessRequest(2,1,"r"));
		InitMem.put(3, new ProcessRequest(2,3,"r"));
		InitMem.put(4, new ProcessRequest(3,3,"r"));
		return InitMem;
	}
	private Hashtable<Integer, ProcessRequest> StatoInizialeMemoriaSwap() {
		Hashtable<Integer, ProcessRequest> InitMem = new Hashtable<Integer, ProcessRequest>();
		InitMem.put(0, new ProcessRequest(1,3,"r"));
		InitMem.put(1, new ProcessRequest(1,4,"r"));
		InitMem.put(2, new ProcessRequest(2,2,"r"));
		InitMem.put(2, new ProcessRequest(2,4,"r"));
		InitMem.put(3, new ProcessRequest(3,1,"r"));
		InitMem.put(4, new ProcessRequest(3,2,"r"));
		InitMem.put(5, new ProcessRequest(3,5,"r"));
		InitMem.put(6, new ProcessRequest(3,6,"r"));
		InitMem.put(7, new ProcessRequest(3,7,"r"));
		return InitMem;
	}

	private Hashtable<Integer, ProcessRequest> MemoriaCentrale1() {
		Hashtable<Integer, ProcessRequest> InitMem = new Hashtable<Integer, ProcessRequest>();
		InitMem.put(0, new ProcessRequest(1,3,"r"));
		InitMem.put(1, new ProcessRequest(1,2,"r"));
		InitMem.put(2, new ProcessRequest(2,1,"r"));
		InitMem.put(3, new ProcessRequest(2,3,"r"));
		InitMem.put(4, new ProcessRequest(3,3,"r"));
		return InitMem;
	}
	
	private Hashtable<Integer, ProcessRequest> MemoriaSwap1() {
		Hashtable<Integer, ProcessRequest> InitMem = new Hashtable<Integer, ProcessRequest>();
		InitMem.put(0, new ProcessRequest(1,1,"r"));
		InitMem.put(1, new ProcessRequest(1,4,"r"));
		InitMem.put(2, new ProcessRequest(2,2,"r"));
		InitMem.put(2, new ProcessRequest(2,4,"r"));
		InitMem.put(3, new ProcessRequest(3,1,"r"));
		InitMem.put(4, new ProcessRequest(3,2,"r"));
		InitMem.put(5, new ProcessRequest(3,5,"r"));
		InitMem.put(6, new ProcessRequest(3,6,"r"));
		InitMem.put(7, new ProcessRequest(3,7,"r"));
		return InitMem;
	}
	private Hashtable<Integer, ProcessRequest> MemoriaCentrale2() {
		Hashtable<Integer, ProcessRequest> InitMem = new Hashtable<Integer, ProcessRequest>();
		InitMem.put(0, new ProcessRequest(1,3,"r"));
		InitMem.put(1, new ProcessRequest(1,4,"r"));
		InitMem.put(2, new ProcessRequest(2,1,"r"));
		InitMem.put(3, new ProcessRequest(2,3,"r"));
		InitMem.put(4, new ProcessRequest(3,3,"r"));
		return InitMem;
	}
	
	private Hashtable<Integer, ProcessRequest> MemoriaSwap2() {
		Hashtable<Integer, ProcessRequest> InitMem = new Hashtable<Integer, ProcessRequest>();
		InitMem.put(0, new ProcessRequest(1,1,"r"));
		InitMem.put(1, new ProcessRequest(1,2,"r"));
		InitMem.put(2, new ProcessRequest(2,2,"r"));
		InitMem.put(2, new ProcessRequest(2,4,"r"));
		InitMem.put(3, new ProcessRequest(3,1,"r"));
		InitMem.put(4, new ProcessRequest(3,2,"r"));
		InitMem.put(5, new ProcessRequest(3,5,"r"));
		InitMem.put(6, new ProcessRequest(3,6,"r"));
		InitMem.put(7, new ProcessRequest(3,7,"r"));
		return InitMem;
	}
	private Hashtable<Integer, ProcessRequest> MemoriaCentrale2a() {
		Hashtable<Integer, ProcessRequest> InitMem = new Hashtable<Integer, ProcessRequest>();
		InitMem.put(0, new ProcessRequest(1,3,"r"));
		InitMem.put(1, new ProcessRequest(1,4,"r"));
		InitMem.put(2, new ProcessRequest(2,1,"r"));
		InitMem.put(3, new ProcessRequest(2,3,"r"));
		InitMem.put(4, new ProcessRequest(3,3,"r"));
		InitMem.put(5, new ProcessRequest(3,4,"r"));
		return InitMem;
	}
}
